package kin.dao.security;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import kin.bean.security.Acl;
import kin.bean.security.AclId;
import kin.bean.security.Module;
import kin.bean.security.Permission;
import kin.manager.security.AclManager;


@Component
public class AclManagerIMP  implements AclManager {
	@Autowired 
//	@Qualifier("sessionFactory")
private SessionFactory sessionFactory;
	
	public void addOrUpdatePermission(String principalType, int principalId,
			int moduleId, int permission, boolean yes) {
		Acl Acl = this.findAclById(principalType, principalId, moduleId);
		if (Acl != null) {
			Acl.setPermission(permission, yes);

		} else {
			Acl = new Acl();
			Acl.setAclId(findAclId(principalType, principalId, moduleId));
			Acl.setPermission(permission, yes);

		}
		
		this.getSessionFactory().getCurrentSession().saveOrUpdate(Acl);
	}

	public Acl findAclById(String principalType, int principalId,
			int moduleId) {

		return (Acl) this.getSessionFactory().getCurrentSession().get(Acl.class,
				this.findAclId(principalType, principalId, moduleId));
	}

	public AclId findAclId(String principalType,int principalId,int moduleId) {
		AclId Aclid = new AclId();
		Aclid.setPrincipalId(principalId);
		Aclid.setPrincipalType(principalType);
		Aclid.setModule((Module) this.getSessionFactory().getCurrentSession().load(Module.class, moduleId));
		return Aclid;

	}

	public void delPermission(String principalType, int principalId,
			int moduleId) {
		this.getSessionFactory().getCurrentSession().delete(this.findAclById(principalType, principalId, moduleId));

	}

	public void addOrUpdateUserExtends(int userId, int moduleId,
			boolean yes) {
		 Acl acl=(Acl) this.findAclById(Acl.TYPE_USER, userId, moduleId);
         if(acl!=null){
        	 acl.setExtends(yes);
        	 
        	 
         }else{
        	 acl=new Acl();
        	
        	 acl.setAclId(findAclId(Acl.TYPE_USER, userId, moduleId));
        	 acl.setExtends(yes);
        	
         }
         this.getSessionFactory().getCurrentSession().saveOrUpdate(acl);
	}

	public boolean hasPermission(int userId, int moduleId, int permission) {
		Acl acl=(Acl) this.findAclById(Acl.TYPE_USER, userId, moduleId);
		 
		 if(acl!=null){
			 int per=acl.getPermission(permission);
			 if(per!=-1){
				 if(per==1){
					 return true;
				 }
				return false; 
			 }
			 }
		
		 Query qc= this.getSessionFactory().getCurrentSession().createQuery("select ur.role.role_id from UsersRoles ur where ur.user.user_id=? order by ur.usersroles_orderNo");
		 qc.setInteger(0, userId);
	
		 List l=qc.list();
		 for(int i=0;i<l.size();i++){
              Integer rid=(Integer)l.get(i);
              acl=(Acl) this.findAclById(Acl.TYPE_ROLE,rid, moduleId);
             /* .setParameter(0,Acl.TYPE_ROLE)
              .setParameter(1,rid)
              .setParameter(2,moduleId).uniqueResult();*/
	         if(acl!=null){
	        	 if(acl.getPermission(permission)==1){
	        		 return true;
	        	 }
	        	 return false;
	         }
 
		 }
		return false;
	}

	public List<Module> findModulesByUser(int userId) {
		Map<Integer, Acl> m = new HashMap<Integer, Acl>();
		

		List rids = this.getSessionFactory().getCurrentSession().createQuery("select ur.role.role_id from UsersRoles ur where ur.user.user_id =? order by ur.usersroles_orderNo desc").setParameter(0, userId).list();
		for (int i = 0; i < rids.size(); i++) {
			String rid = (String) rids.get(i);
			
			List Acls = this.getSessionFactory().getCurrentSession().createQuery("select Acl from Acl as Acl where Acl.AclId.principalId=? and Acl.AclId.principalType=?")
					.setParameter(1, Acl.TYPE_ROLE).setParameter(0, rid).list();
			for (int j = 0; j < Acls.size(); j++) {
				Acl Acl = (Acl) Acls.get(j);
				m.put(Acl.getAclId().getModule().getModule_id(), Acl);
			}
		}
		
		List l = this.getSessionFactory().getCurrentSession()
				.createQuery(
						"select Acl from Acl as Acl where Acl.AclId.principalId=? and Acl.AclId.principalType=? and Acl.extendsState=0")
				.setParameter(0, userId).setParameter(1, Acl.TYPE_USER).list();
		for (int j = 0; j < l.size(); j++) {
			Acl Acl = (Acl) l.get(j);
			m.put(Acl.getAclId().getModule().getModule_id(), Acl);
		}
		
		for (int i = 0; i < m.size(); i++) {

			String temp = (String) m.keySet().toArray()[i];
			System.out.println(temp + "--------");
			Acl Acls = (Acl) m.get(temp);
			if (Acls.getPermission(Permission.Read) == Acl.ACL_NO) {
				m.remove(temp);
			}
		}
		
		 for(int i=0;i<m.keySet().size();i++){
			 System.out.println(m.keySet().toArray()[i]);}
 
		 List s=this.getSessionFactory().getCurrentSession()
			.createQuery("select m from Module m where m.module_id in (:ids)")
			.setParameterList("ids", m.keySet()).list();
	    return s;
	}

	

	public void delPermissionsByRole(int userId) {
		Map<Integer,Acl> m=new HashMap<Integer,Acl>();
		
		List rids=this.getSessionFactory().getCurrentSession().createQuery("select ur.role.role_id from UsersRoles ur where ur.user.user_id =? order by ur.usersroles_orderNo desc").setParameter(0,userId).list();
		for(int i=0;i<rids.size();i++){
			String rid=(String) rids.get(i);
			//����ɫID����Acl�б�
			List Acls= this.getSessionFactory().getCurrentSession().createQuery("select Acl from Acl as Acl where Acl.AclId.principalId=? and Acl.AclId.principalType=?")
	        .setParameter(1,Acl.TYPE_ROLE)
	        .setParameter(0,rid).list();
			for(int j=0;j<Acls.size();j++){
			Acl Acl=(Acl) Acls.get(j);
			m.put(Acl.getAclId().getModule().getModule_id(), Acl);
			}
		}
		
		List<Acl> ad=this.getSessionFactory().getCurrentSession().createQuery("select Acl from Acl Acl where Acl.AclId.module.module_id in (:ids)").setParameterList("ids",m.keySet()).list();
		for(Acl a:ad){
			if(a.getAclState()!=0){
			a.setAclState(0);
			this.getSessionFactory().getCurrentSession().update(a);
			}
			
		}
		

	}

	

	
	public List findPermissionsByRole(int userId) {
		// TODO Auto-generated method stub
		return null;
	}



	public List<Acl> findAll() {
         //this.getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery("from Acl");
		return this.getSessionFactory().getCurrentSession().createQuery("from Acl").list();
	}
	
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	
	public void delAclByModule(int moduleId) {
		this.getSessionFactory().getCurrentSession().createQuery("delete from Acl acl where acl.aclId.module.module_id =?").setParameter(0, moduleId).executeUpdate();

		/*Criteria ca=this.getSessionFactory().getCurrentSession().createCriteria(Acl.class);
	    ca.list();*/
	    
	    //List<Acl> acls = this.getSessionFactory().getCurrentSession().createCriteria(Acl.class).list();
	    
	   // System.out.println("==============size===================="+acls.size());
		
	/*	
		for(Acl acl:ls){
			this.getSessionFactory().getCurrentSession().delete(acl);
		}*/
	}

	public void delPermissionsByModule(int moduleId,int permission) {

		List<Acl> acls=this.getSessionFactory().getCurrentSession().createQuery("from Acl acl where acl.aclId.module.module_id =?").setParameter(0,moduleId).list();
		
		for(Acl acl:acls){
			acl.setPermission(permission, false);
			this.getSessionFactory().getCurrentSession().saveOrUpdate(acl);
		}
		System.out.println("==============sizer===================="+acls.size());
		/*for(int i=0;i<rids.size();i++){
			String rid=(String) rids.get(i);
			//����ɫID����Acl�б�
			List Acls= this.getSessionFactory().getCurrentSession().createQuery("select Acl from Acl as Acl where Acl.AclId.principalId=? and Acl.AclId.principalType=?")
	        .setParameter(1,Acl.TYPE_ROLE)
	        .setParameter(0,rid).list();
			for(int j=0;j<Acls.size();j++){
			Acl Acl=(Acl) Acls.get(j);
			m.put(Acl.getAclId().getModule().getModule_id(), Acl);
			}
		}
		
		List<Acl> ad=this.getSessionFactory().getCurrentSession().createQuery("select Acl from Acl Acl where Acl.AclId.module.module_id in (:ids)").setParameterList("ids",m.keySet()).list();
		for(Acl a:ad){
			if(a.getAclState()!=0){
			a.setAclState(0);
			this.getSessionFactory().getCurrentSession().update(a);
			}
			
		}*/
		

	}

	@Override
	public List<Acl> findByUser(String principalType,int userId) {
		return this.getSessionFactory().getCurrentSession().createQuery("from Acl as acl where acl.aclId.principalId=? and acl.aclId.principalType=?").setParameter(0,userId).setParameter(1,  principalType).list();
	}
	
}
